#include "../logs/clxlog.h"
#include <unistd.h>


// 落地扩展，以时间作为滚动的依据的滚动文件落地方式
enum class TimeGap {
    GAP_SECOND,
    GAP_MINUTE,
    GAP_HOUR,
    GAP_DAY
};

class RollByTimeSink : public clxlog::LogSink {
    public:
        RollByTimeSink(const std::string &basename, TimeGap gap_type) 
            : _basename(basename), _cur_gap(0)
        {
            switch(gap_type) {
                case TimeGap::GAP_SECOND : _gap_size = 1  ;             break;
                case TimeGap::GAP_MINUTE : _gap_size = 60 ;             break;
                case TimeGap::GAP_HOUR   : _gap_size = 60 * 60 ;        break;
                case TimeGap::GAP_DAY    : _gap_size = 60 * 60 * 24 ;   break;
            }
            _cur_gap = clxlog::util::Data::now() / _gap_size;
            std::string filename = createNewFile();
            clxlog::util::File::createDirectory(clxlog::util::File::path(filename));
            _ofs.open(filename, std::ios::binary | std::ios::app);
            assert(_ofs.good());
        }

        void log(const char* data, size_t len) {
            time_t cur = clxlog::util::Data::now();
            if ((cur / _gap_size) != _cur_gap) {
                _ofs.close();
                std::string filename = createNewFile();
                _ofs.open(filename, std::ios::binary | std::ios::app);
                assert(_ofs.good());
            }
            _ofs.write(data, len);
            assert(_ofs.good());
        }

    private:
        std::string createNewFile() {
            time_t t = clxlog::util::Data::now();
            struct tm lt;
            localtime_r(&t, &lt);
            std::stringstream filename;
            filename << _basename;
            filename << (lt.tm_year + 1900);
            filename << "-";
            filename << (lt.tm_mon + 1);
            filename << "-";
            filename << lt.tm_mday;
            filename << " ";
            filename << lt.tm_hour;
            filename << ":";
            filename << lt.tm_min;
            filename << ":";
            filename << lt.tm_sec;
            filename << ".log";
            return filename.str();
        }
    private:
        std::string _basename;
        size_t _cur_gap;
        size_t _gap_size;
        std::ofstream _ofs;
};

void demo() {
    clxlog::LoggerBuilder::ptr builder(new clxlog::GlobalLoggerBuilder());
    builder->buildLoggerType(clxlog::LoggerType::LOGGER_ASYNCH);
    builder->buildLoggerLevel(clxlog::LogLevel::value::WARN);
    builder->buildLoggerName("clx_asynch_logger");
    builder->buildLoggerFormatter("[%c][%f:%l]%m%n");
    builder->buildSink<RollByTimeSink>("./logfile/roll-asynch-by-size", TimeGap::GAP_SECOND);
    clxlog::Logger::ptr logger = builder->build();
    size_t cur = clxlog::util::Data::now();

    while (clxlog::util::Data::now() < cur + 5) {
        logger->fatal("这是一条测试日志器");
        usleep(1000);
    }
}
int main() {
    demo();
    return 0;
}

